#define MSWEB_C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
//user header
#include <libmscommon/mscommon.h>
#include <libmscommon/msstring.h>
#include <libmscommon/mstime.h>
#include <libmscommon/msmd.h>
#include <libmscommon/msfifo.h>
#include <libmscommon/msthread.h>
#include <libmscommon/msepoll.h>
#include <libmslog/mslog.h>
#include "msweb.h"
#include "msperformance.h"
#include "msuser_control.h"
extern OSInfo  os_info;

#define FLAG "MSWEB"
#define MSWE_ACCESS_CONTROL \
	"Access-Control-Allow-Origin: *\r\n" \
	"Access-Control-Allow-Headers: X-Requested-With\r\n" \
	"Access-Control-Allow-Methods: GET,POST,OPTIONS\r\n" \
	"X-Frame-Options: SAMEORIGIN\r\n"

static ms_string msweb_basekey="msos@MSWEB&837611-8475639204543217562819234513145784541512";

#define MSWEB_DBG_RECV		ms_false
#define MSWEB_DBG_ICT	ms_false

void msweb_api_ok(char *outbuf)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_OK,netStateCode_string[NETSTATE_CODE_OK]
	);	
}
ms_bool msweb_api_ok_data(ms_string strBasekey,char *jsondata,char *outbuf)
{	
	char AuthentString[256] = {0};
	msdenc_api_encStr2(AuthentString,strBasekey,jsondata,FLAG,ms_null);
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/json\r\n"
		MSWE_ACCESS_CONTROL
		"Content-Length: %d\r\n"
		"Token: %s\r\n"
		"Connection:close\r\n"
		"\r\n"
		"%s\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_OK,netStateCode_string[NETSTATE_CODE_OK],
		(ms_s32)ms_buflen(jsondata),AuthentString,
		jsondata
	);
	return ms_true;
}
void msweb_api_unauthorizedAccess(char *outbuf,DECSTRRet ret_enpmatch)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Desinfo: Unauthorized access(%d)\r\n"
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_FORBIDDEN,netStateCode_string[NETSTATE_CODE_FORBIDDEN],ret_enpmatch	
	);	
}
void msweb_api_methodNotAllowed(char *outbuf)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_METHOD,netStateCode_string[NETSTATE_CODE_METHOD]	
	);	
}
void msweb_api_badRequest(char *outbuf)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_BAD_REQUEST,netStateCode_string[NETSTATE_CODE_BAD_REQUEST]	
	);	
}

void msweb_api_frequentVisits(char *outbuf,ms_s32 intercepttime)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Desinfo: Visiting Too Often(access interval is %d us)\r\n"
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_FORBIDDEN,netStateCode_string[NETSTATE_CODE_FORBIDDEN],
		intercepttime
	);	
}
void msweb_api_initFirst(char *outbuf)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Desinfo: Server Is Initializing\r\n"
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_INTERNAL,netStateCode_string[NETSTATE_CODE_INTERNAL]	
	);	
}
void msweb_api_disableOut(char *outbuf)
{
	ms_sprintfs(outbuf,
		"%s %d %s\r\n"
		"Content-type: text/html\r\n"
		MSWE_ACCESS_CONTROL
		"Desinfo: Server Is disableout\r\n"
		"Connection:close\r\n"
		"\r\n",
		MSPTC_VERSION_HTTP,NETSTATE_CODE_INTERNAL,netStateCode_string[NETSTATE_CODE_INTERNAL]	
		
	);	
}

void msweb_api_headTitle(char *outbuf,char *title,char *page)
{
	char tempbuf[10240]={0};
	ms_strcats(tempbuf,outbuf,
		"<!DOCTYPE html>"
		"<html lang=\"en\">"
		"<head>"
		"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"
			"<title>%s </title>"
		"</head>"
		"<body >"
		"<div>"
		"<tr>"
		"</tr>"
			"<h1 "MSWEB_H1_STYLE"> ""<b>%s</b>""</h1>"
		"</div>"
		"<hr class=\"heading\">"
		,title
		,page) ;	
}
void msweb_api_cmHeadTitle(char *outbuf,char *title,char *page_info,WEBHOSTInfo webhost_info)
{
	char tempbuf[5120]={0};
	ms_strcats(tempbuf,outbuf,
		"<!DOCTYPE html>"
		"<html lang=\"en\">"
		"<head>"
		"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"
			"<title>%s-%s </title>"
			"<link rel=\"stylesheet\" href=\"http://%s:%d/mscore/css/screen.css\" type=\"text/css\" media=\"screen, projection\">"
			"<link rel=\"stylesheet\" href=\"http://%s:%d/mscore/css/mscore.css\" type=\"text/css\" />"
			"<link rel=\"shortcut icon\" href=\"http://%s:%d/mscore/img/mscore-logo.png\" type=\"image/x-icon\" />"
		"</head>"
		"<div>"		
			"<h1 "MSWEB_H1_STYLE"> ""<b>%s</b>""</h1>"
		"</div>"
		"<hr class=\"heading\">",
		title,webhost_info.server_ip,
		webhost_info.server_host,
		webhost_info.server_host,
		webhost_info.server_host,
		page_info) ;	
}
void msweb_api_tailTitle(char *outbuf, WEBHOSTInfo webhost_infos,ms_string version,ms_string mail_list)
{
	char tempbuf[2048]={0};
	//ms_strcats(tempbuf,outbuf,"<h2 style=\"margin-top:2%;color:black\"; ><b>EXTERTION INFO</b></h2>");
	ms_strcats(tempbuf,outbuf,	
		"<hr noshade=\"noshade\" size=\"1\" >"
		"<br>sysversion:%s"
		"<br>builddate:%s %s"
		"<br>concatus:%s<br>"
		"</body></html>",
		version,
		__DATE__,__TIME__,
		mail_list
	);
	ms_s08 strCurDTime[64]={0};
	ms_strcats(tempbuf,outbuf,	
		"<div class=\"span-23 last copyright\" "MSWEB_HT1_STYLE" >&nbsp;&#169;&nbsp;rightsreserved %s</div>"
		"</body></html>",mstime_api_curDTime(mstime_fmt_datetime,strCurDTime)
 	);
}

void msweb_api_formatConvert(char * inbuf,char *outbuf,int len)
{
	int index=0;
	int index2=0;
	if(len>0){
		ms_memcpy(&outbuf[index2], AH_WEB, ms_buflen(AH_WEB));
		index2+=ms_buflen(AH_WEB);
	}
	for(index=0;index<len;index++){
		if('\r'==inbuf[index]||'\n'==inbuf[index]){
			ms_memcpy(&outbuf[index2], AH_WEB, ms_buflen(AH_WEB));
			index2+=ms_buflen(AH_WEB);
		}else{
			outbuf[index2]=inbuf[index];
			index2++;
		}
	}
	outbuf[index2]=0;
}

void msweb_api_formatConvert2(char * inbuf,char *outbuf,int len)
{
	int index=0;
	int index2=0;
	for(index=0;index<len;index++){
		if(0x0a==inbuf[index]||'\n'==inbuf[index]){
			ms_memcpy(&outbuf[index2], SPACE_WEB, ms_buflen(SPACE_WEB));
			index2+=ms_buflen(SPACE_WEB);
		}else{
			outbuf[index2]=inbuf[index];
			index2++;
		}
	}
	outbuf[index2]=0;
}
ms_s32 msweb_api_charConvert(ms_string ms_in instr,ms_string ms_out outstr,ms_u32 ms_in len)
{
	int index=0;
	int outlen=0;
	for(index=0;index<len;index++){
		switch(instr[index]){
			case '\n':
				memcpy(&outstr[outlen],"<br>",4);
				outlen+=4;
				break;
				
			case '\r':	//drop
				break;
			default:
				outstr[outlen]=instr[index];
				outlen+=1;
				break;	
		}
	}
	return outlen;
}

ms_s32 msweb_api_convert2Char(ms_string ms_in instr,ms_string ms_out outstr,ms_u32 ms_in len)
{
	int index=0;
	int outlen=0;
	for(index=0;index<len;index++){
		if(ms_strncmp_seq(&instr[index], "%22")){
			outstr[outlen]='"';
			outlen+=1;
			index+=2;
		}else if(ms_strncmp_seq(&instr[index], "%20")){
			outstr[outlen]=' ';
			outlen+=1;
			index+=2;
		}else{
			outstr[outlen]=instr[index];
			outlen+=1;
		}
	}
	return outlen;
}

ENUPROTOCOLIndex msweb_api_getProtocol(WEBREQUESTContext *prequest_ctt)
{
	ms_pamcheckRet(msptc_unknow, prequest_ctt, "prequest_ctt");
	ENUPROTOCOLIndex pindex=msptc_unknow;
	ms_verbose("protocol:%s,url:%s", prequest_ctt->protocol,prequest_ctt->url);
	if(ms_true==msstr_api_isCasestr(prequest_ctt->protocol, "RTSP" )){
		ms_verbose("------rtsp");
		pindex=msptc_rtsp;
	}else if(ms_true==msstr_api_isCasestr(prequest_ctt->protocol, "HTTP" )){
		if((ms_true==msstr_api_isCasestr(prequest_ctt->protocol, "hls") )
			||(ms_true==msstr_api_isCasestr(prequest_ctt->url, ".m3u8") )){
			ms_verbose("------hls");
			pindex=msptc_hls;
		}else{
			ms_verbose("------http");
			pindex=msptc_http;
		}
	}
	return pindex;
}
MSWEBUSERTYpe msweb_api_getUserType(ms_string userInfo)
{
	if(msstr_api_isCasestr(userInfo, enp_exstring_dev)){
		//ms_debug("--------dev:%s,%s",userInfo,enp_exstring_dev);
		return msweb_usertype_dev;
	}else if(msstr_api_isCasestr(userInfo, enp_exstring_inner)){
		//ms_debug("--------inner:%s,%s",userInfo,enp_exstring_dev);
		return msweb_usertype_inner;
	}else{
		//ms_debug("--------nor:%s,%s",userInfo,enp_exstring_dev);
		return msweb_usertype_nor;
	}
}
ms_void msweb_api_loginInit(MSWEBLOGINContext *pWLGCtt,ms_string user1,ms_string user2,ms_string pwd1,ms_string pwd2)
{
	if(ms_false==pWLGCtt->flag_init){
		ms_memset0(pWLGCtt, ms_bufsize(MSWEBLOGINRet));
		mslock_api_init(&pWLGCtt->mslock_ctt, "login",lockType_mutex);
		pWLGCtt->flag_init=ms_true;
	}
mslock_api_do(&pWLGCtt->mslock_ctt);
	pWLGCtt->name[0]=user1;
	pWLGCtt->name[1]=user2;
	pWLGCtt->pwd[0]=pwd1;
	pWLGCtt->pwd[1]=pwd2;
mslock_api_undo(&pWLGCtt->mslock_ctt);
}
ms_void msweb_api_loginDeinit(MSWEBLOGINContext *pWLGCtt)
{
	if(ms_true==pWLGCtt->flag_init){
		mslock_api_deinit(&pWLGCtt->mslock_ctt);
		ms_memset0(pWLGCtt, ms_bufsize(MSWEBLOGINRet));
		pWLGCtt->flag_init=ms_false;
	}
}
MSWEBLOGINRet msweb_api_login(MSWEBLOGINContext *pWLGCtt,ms_string outstr)
{
	MSWEBLOGINRet ret=msweb_login_ret_nouser;
mslock_api_do(&pWLGCtt->mslock_ctt);
//兼容：支持用户名的查
	if((ms_null!=pWLGCtt->name[0])&&(ms_null!=pWLGCtt->name[1])&&ms_strncmp_snaeq(pWLGCtt->name[0],pWLGCtt->name[1])){
		ret=msweb_login_ret_nouser;
		goto msend;
	}
//密码对比	
	if(MSWEB_LOGIN_FAILED_NUM==pWLGCtt->errNum){
		//大于15分钟则解锁
		if(mstime_api_counterAsyncSec(&pWLGCtt->lockedBaseTime, ms_minutes(MSWEB_LOGIN_LOCKED_TIME))){
			pWLGCtt->lockedBaseTime=0;
			pWLGCtt->errNum=0;
		}else{
			ms_sprintfs(pWLGCtt->exStr, "账号已被锁定，请稍后再进行尝试");
			ret=msweb_login_ret_locked;
			goto msend;
		}
	}
	if((ms_null!=pWLGCtt->pwd[0])&&(ms_null!=pWLGCtt->pwd[1])&&ms_strncmp_saeq(pWLGCtt->pwd[0],pWLGCtt->pwd[1])){
		pWLGCtt->errNum=0;
		ret=msweb_login_ret_ok;
		goto msend;
	}else{
		//距离上一次输入超过5分钟
		if(mstime_api_counterAsyncSec(&pWLGCtt->lastErrBaseTime, ms_minutes(5))){
			pWLGCtt->errNum=0;
		}
		pWLGCtt->errNum++;
		pWLGCtt->lastErrBaseTime=mstime_api_sec();
		if(5==pWLGCtt->errNum){
			pWLGCtt->lockedBaseTime=mstime_api_sec();
			ms_sprintfs(pWLGCtt->exStr, "账号将被锁定%d分钟",MSWEB_LOGIN_LOCKED_TIME);
		}else{
			ms_sprintfs(pWLGCtt->exStr, "剩余%d次，否则将被锁定%d分钟",(5-pWLGCtt->errNum),MSWEB_LOGIN_LOCKED_TIME);
		}
		ret=msweb_login_ret_failed;
		goto msend;
	}	
msend:	
	mslock_api_undo(&pWLGCtt->mslock_ctt);
	return ret;
}

static ms_u32 msev_innerapi_getNumCp(MSEVContext *pmsev_ctt)
{
	if(ms_null==pmsev_ctt){
		return 0;
	}
	MSEVCPContext *pmsgw_ctt_list=pmsev_ctt->pCp_ctt;
	MSEVCPContext *pmsgw_ctt=&pmsgw_ctt_list[0];
	if(ms_null==pmsgw_ctt){
		return 0;
	}
	//get request_list num
	mslock_api_do(pmsgw_ctt->pMslockCtt_cp);
	ms_u32 totalnum=msfifo_api_listTotalNum(pmsgw_ctt->ppFifoListCtt_cp);
	mslock_api_undo(pmsgw_ctt->pMslockCtt_cp);
	return totalnum;
}
static ms_u32 msev_innerapi_getNumDcp(MSEVContext *pmsev_ctt)
{
	if(ms_null==pmsev_ctt){
		return 0;
	}
	MSEVCPContext *pmsgw_ctt_list=pmsev_ctt->pCp_ctt;
	MSEVCPContext *pmsgw_ctt=&pmsgw_ctt_list[0];
	if(ms_null==pmsgw_ctt){
		return 0;
	}
	//get request_list num
	mslock_api_do(pmsgw_ctt->pMslockCtt_dcp);
	ms_u32 totalnum=msfifo_api_listTotalNum(pmsgw_ctt->ppFifoListCtt_dcp);
	mslock_api_undo(pmsgw_ctt->pMslockCtt_dcp);
	return totalnum;
}
static ms_bool msev_innerapi_ictBlackResaddr(ms_string ipaddr,ms_bool flag_ictResAddr)
{
	ms_bool falg_intercept=ms_false;
	if((flag_ictResAddr&&(ms_true==msnet_api_isResIpaddr(ipaddr)))
		||(ms_true==msmsusrctl_api_isBlack(ipaddr))){
		falg_intercept=ms_true;
	}
	return falg_intercept;
}

static ms_bool msev_innerapi_ictEnter(MSEVIctContext **ppIct_ctt,ms_string ipaddr,ms_s32 fd,
	ms_s32 ictAccessTime_us,ms_bool flag_ictAccess,ms_bool flag_ictResAddr)
{
	ms_bool flag_black=ms_false;
	ms_bool flag_intercept=ms_false;
	ms_bool flag_find=ms_false;
	if(-1==ictAccessTime_us){
		ictAccessTime_us=MSWEBAPI_INTERCEPT_PERTIME;
	}
	if(ms_true==msmsusrctl_api_isWhite(ipaddr)){
		return ms_false;
	}
	if(ms_false==flag_ictAccess){	//dsiable intercept
		ms_enVerbose(MSWEB_DBG_ICT,"disable intercept:is  %s   is black addr",ipaddr);
		if(msev_innerapi_ictBlackResaddr(ipaddr,flag_ictResAddr)){
			ms_enVerbose(MSWEB_DBG_ICT,"disable intercept:%s   is blackaddr",ipaddr);
			flag_intercept=ms_true;
			flag_black=ms_true;
		}else{
			ms_enVerbose(MSWEB_DBG_ICT,"disable intercept:%s   isnot blackaddr",ipaddr);
		}
		return flag_intercept;
	}else{
		while(ms_null!=(*ppIct_ctt)){
			if(ms_strncmp_saeq((*ppIct_ctt)->ipaddr, ipaddr)){
				//reset data
				if((*ppIct_ctt)->numTotal>30000000){	
					(*ppIct_ctt)->numper=(*ppIct_ctt)->baseNum=(*ppIct_ctt)->numTotal=(*ppIct_ctt)->numIct=0;
					(*ppIct_ctt)->lastReqTime=mstime_api_us(); 
					(*ppIct_ctt)->baseTime=mstime_api_us(); 
				}
				ms_enVerbose(MSWEB_DBG_ICT,"intercept:find  %s",ipaddr);
				flag_find=ms_true;
				(*ppIct_ctt)->numTotal+=1;
				if(msev_innerapi_ictBlackResaddr(ipaddr,flag_ictResAddr)){
					(*ppIct_ctt)->numIct+=1;
					ms_enVerbose(MSWEB_DBG_ICT,"intercept:%s   is blackaddr",ipaddr);
					flag_intercept=ms_true;
				}else{
					ms_enVerbose(MSWEB_DBG_ICT,"intercept:%s   isnot blackaddr",ipaddr);
					if((mstime_api_us() - (*ppIct_ctt)->lastReqTime)>ictAccessTime_us){
						ms_debug("intercept:ok--  %s",ipaddr);
						(*ppIct_ctt)->lastReqTime=mstime_api_us(); 
					}else{
						ms_debug("intercept:403--  %s",ipaddr);
						(*ppIct_ctt)->numIct+=1;
						flag_intercept=ms_true;
					}
				}
				//get numper
				if((mstime_api_us() - (*ppIct_ctt)->baseTime)>ms_usmseconds(980)){
					(*ppIct_ctt)->baseTime=mstime_api_us(); 
					(*ppIct_ctt)->numper=(*ppIct_ctt)->numTotal-(*ppIct_ctt)->baseNum;
					(*ppIct_ctt)->baseNum=(*ppIct_ctt)->numTotal;
				}
			}
			ppIct_ctt=&(*ppIct_ctt)->next;
		}
		//new ipaddr,add to list
		if(ms_false==flag_find){
			ms_enVerbose(MSWEB_DBG_ICT,"intercept:add  %s",ipaddr);
			MSEVIctContext *new_preclient_ctt=ms_null;
			ms_mallocDes_retErr(ms_false,new_preclient_ctt, ms_bufsize(MSEVIctContext), "MSEVIctContext","new_preclient_ctt");
			new_preclient_ctt->next=ms_null;
			ms_strcpy(new_preclient_ctt->ipaddr, ipaddr);
			new_preclient_ctt->baseTime=new_preclient_ctt->lastReqTime=mstime_api_us(); 
			new_preclient_ctt->numTotal+=1;
			new_preclient_ctt->numper=1;
			new_preclient_ctt->baseNum=0;
			if(msev_innerapi_ictBlackResaddr(ipaddr,flag_ictResAddr)){
				ms_enVerbose(MSWEB_DBG_ICT,"intercept:%s   is blackaddr",ipaddr);
				ms_strcpy(new_preclient_ctt->des, msstr_intercept_black);
				new_preclient_ctt->numIct+=1;
				flag_intercept=ms_true;
				flag_black=ms_true;
			}else{
				ms_enVerbose(MSWEB_DBG_ICT,"intercept:%s   isnot blackaddr",ipaddr);
				ms_strcpy(new_preclient_ctt->des, msstr_intercept_white);
			}
			(*ppIct_ctt)=new_preclient_ctt;
		}

		if((ms_true==flag_intercept)&&(ms_false==flag_black)){
			char outbuf[1024]={0};
			msweb_api_frequentVisits(outbuf,ictAccessTime_us);
			int len=msnet_api_epollSend3(fd,outbuf,ms_buflen(outbuf)); 
			ms_enVerbose(MSWEB_DBG_ICT,"send reply to %s:\r\n %s",ipaddr, outbuf);
			if(!(len>0)){
				ms_error("msnet_api_epollSend3 failed");
			}
			ms_close(fd);
		}
		return flag_intercept;
	}
}

static ms_bool msev_innerapi_ictExit(MSEVIctContext **ppIct_ctt)
{
	MSEVIctContext *pIct_ctt=(*ppIct_ctt);
	MSEVIctContext *pIctCtt_next=ms_null;
	while(ms_null!=pIct_ctt){
		pIctCtt_next=pIct_ctt->next;
		ms_deMalloc(pIct_ctt);
		pIct_ctt=pIctCtt_next;
	}
	return ms_true;
}
static ms_bool msev_innerapi_isException(MSEVClientContext*pEvClient_ctt,ms_bool flag_dcp)
{
	ms_string pItem=(flag_dcp ? "DCP池" :  "CP池");
	//关闭太久没有通信的连接
	ms_u64 chaTime_us=mstime_api_us()-pEvClient_ctt->lastReqTime_us;
	if(ms_noLess(chaTime_us,ms_usseconds(msev_timeout_dropReq))){
		ms_byte intime_str[64]={0};
		mstime_api_us2DTime(&pEvClient_ctt->lastReqTime_us, mstime_fmt_datetime_ex1,intime_str);
		ms_s08 strCurDTime[64]={0};
		ms_waring("[%s]drop %s requ(fd:%d),lastReqTime:%s,now:%s",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pEvClient_ctt->fd,intime_str,
					mstime_api_curDTime(mstime_fmt_datetime_ex1,strCurDTime));
		msev_api_logfile(pEvClient_ctt, "因为连接超时被%s丢弃,超时时间%d秒",pItem,msev_timeout_dropReq);
		return ms_true;
	}
	//关闭连接异常的连接
	char str_tcpi_state[128]={0};
	if(ms_false==msnet_api_isTcpStateOK(pEvClient_ctt->fd,ms_null ,str_tcpi_state) ){
		ms_waring("[%s]drop %s requ(fd:%d),str_tcpi_state:%s",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pEvClient_ctt->fd,str_tcpi_state);
		msev_api_logfile(pEvClient_ctt, "因为连接状态异常被%s丢弃(%s)",pItem,str_tcpi_state);
		return ms_true;
	}
	return ms_false;
}
static ms_void msev_innerapi_close(MSEVDCPContext *pdcp_ctt,MSFIFOLISTContext **ppFifoList_ctt,int msepoll_fd,
	MSFIFOLISTContext **ppFifoList_cur,MSFIFOLISTContext **ppFifoList_pre,ms_u32 *pnum_drop)
{
	MSFIFOLISTContext *pFifoList_cur= (*ppFifoList_cur);
	MSFIFOLISTContext *pFifoList_next=(MSFIFOLISTContext *) (pFifoList_cur->next);
	MSFIFOLISTContext *pFifoList_pre=(*ppFifoList_pre);

	MSEVClientContext*pEvClient_ctt=pFifoList_cur->ptr;
	if(msepoll_del(msepoll_fd,pEvClient_ctt->fd,pEvClient_ctt->event_opt)<0){
		ms_error("msepoll_del-msepollin   failed(client_fd:%d)",pEvClient_ctt->fd);
	}
	if(ms_null!=pFifoList_cur){
		if(msev_state_connecting==pEvClient_ctt->state){//还未处理的请求直接丢掉
			close(pEvClient_ctt->fd);
			msfifo_api_listDemalloc(ppFifoList_cur);
		}else{	//使用中的请求，则需要告知上层应用
			pEvClient_ctt->state=msev_state_close;
			pEvClient_ctt->lastReqTime_us=mstime_api_us();
			mslock_api_do(pdcp_ctt->pLockCtt_cp);
			msfifo_api_listIn(pdcp_ctt->ppFifoListCtt_cp,pFifoList_cur);
			mslock_api_signal(pdcp_ctt->pLockCtt_cp,ms_false);
			mslock_api_undo(pdcp_ctt->pLockCtt_cp);
		}
		(*ppFifoList_cur)=pFifoList_next;
		(*pnum_drop)+=1;
	}
	if( ms_null!=pFifoList_pre){//如果目标不是表头，那么直接删除
		pFifoList_pre->next=pFifoList_next;
	}else{//如果目标是表头，那么需要重新修改表头
		(*ppFifoList_pre)=(MSFIFOLISTContext *)pFifoList_next;
		(*ppFifoList_ctt)=(*ppFifoList_pre);
	}
}

static ms_void msev_innerapi_update(MSFIFOLISTContext **ppFifoList_ctt,ms_u32 num_drop)
{
	if(num_drop>0){
		MSFIFOLISTContext *pFifoList_tmp=(*ppFifoList_ctt);
		while (pFifoList_tmp != ms_null){
			pFifoList_tmp->total_num-=num_drop;
			pFifoList_tmp= pFifoList_tmp->next;
		}
	}
}
static MSFIFOLISTContext *msev_innerapi_findOut(MSEVDCPContext *pdcp_ctt,MSFIFOLISTContext **ppFifoList_ctt,ms_s32 fd,int msepoll_fd,ms_bool flag_drop)
{
	MSFIFOLISTContext *pFifoList_cur= (*ppFifoList_ctt);
	MSFIFOLISTContext *pFifoList_pre=ms_null;
	ms_u32 num_drop=0;
	while (pFifoList_cur != ms_null){
		MSEVClientContext*pEvClient_ctt=pFifoList_cur->ptr;
		MSFIFOLISTContext * pFifoList_next=(MSFIFOLISTContext *) (pFifoList_cur->next);
		//ms_debug("pheader_fifolist_ctt-------------num:%d,fd:%d",msfifo_api_listTotalNum(ppFifoList_ctt),pEvClient_ctt->fd);
		if(pEvClient_ctt->fd==fd){
			if( ms_null!=pFifoList_pre){//如果目标不是表头，那么直接删除
				pFifoList_pre->next=pFifoList_next;
			}else{
				pFifoList_pre=(MSFIFOLISTContext *)pFifoList_next;//如果目标是表头，那么需要重新修改表头
				(*ppFifoList_ctt)=pFifoList_pre;
			}
			//更新数量
			msev_innerapi_update(ppFifoList_ctt, (num_drop+1));
			//对目标进行处理
			//ms_info("close---%d,total_num:%d",pEvClient_ctt->fd,pFifoList_cur->total_num);
			if(msepoll_del(msepoll_fd,pEvClient_ctt->fd,pEvClient_ctt->event_opt)<0){
				ms_error("msepoll_del-msepollin   failed(client_fd:%d)",pEvClient_ctt->fd);
			}
			if(ms_true==flag_drop){
				if(ms_null!=pFifoList_cur){
					close(pEvClient_ctt->fd);
					msfifo_api_listDemalloc(&pFifoList_cur);
				}
				return ms_null;
			}else{
				return pFifoList_cur;
			}
		}
		pFifoList_pre=pFifoList_cur;
		if(pFifoList_cur != ms_null){
			pFifoList_cur=pFifoList_cur->next;
		}
	}
	msev_innerapi_update( ppFifoList_ctt, num_drop);
	return ms_null;
}

static ms_void msev_innerapi_dcpExceptionHandle(MSEVDCPContext *pdcp_ctt,MSFIFOLISTContext **ppFifoList_ctt,int efd,ms_u32 maxNum,ms_string name)
{
	MSFIFOLISTContext *pFifoList_cur= (*ppFifoList_ctt);
	MSFIFOLISTContext*pFifoList_pre=ms_null;
	ms_u32 num_drop=0;
	ms_u32 totalnum=msfifo_api_listTotalNum(ppFifoList_ctt);

	ms_bool flag_tooMany=(ms_noLess(totalnum, maxNum)) ? ms_true : ms_false;

	if(ms_true==flag_tooMany){//池子里面请求太多，处理不过来了，干脆全部清除
		ms_waring("[%s]too many requ,drop all requ ,totalnum, maxNum:%d,%d",name,totalnum, maxNum);
	}
	while (pFifoList_cur != ms_null){
		MSFIFOLISTContext * pFifoList_next=(MSFIFOLISTContext *) (pFifoList_cur->next);
		MSEVClientContext * pEvClient_ctt=(MSEVClientContext *)pFifoList_cur->ptr;
		if(ms_true==flag_tooMany ||(ms_true==msev_innerapi_isException(pEvClient_ctt,ms_true)) ){
			if(ms_true==flag_tooMany){
				msev_api_logfile(pEvClient_ctt, "因为连接太多被丢弃(总连接,最大允许连接:%d,%d)",totalnum, maxNum);
			}
			msev_innerapi_close(pdcp_ctt,ppFifoList_ctt,efd, &pFifoList_cur, &pFifoList_pre, &num_drop);
		}
		pFifoList_pre=pFifoList_cur;
		if(pFifoList_cur != ms_null){
			pFifoList_cur=pFifoList_cur->next;
		}
	}
	msev_innerapi_update( ppFifoList_ctt, num_drop);
}
static ms_u32 msev_innerapi_getTdCpNum(ms_u32 tdCpNum,MSEVTDCPType tdCpType)
{
	ms_u32 cpuNum=msmd_api_getCpuNum();
	ms_u32 cpuNum2=ms_max(cpuNum,msev_tdCp_numDefault);
	ms_u32 tdCpNum_ret=0;
	switch(tdCpType){
		case msev_tdcp_maxnum1:
			tdCpNum_ret=ms_max(tdCpNum,cpuNum);
			break;
		case msev_tdcp_maxnum2:
			tdCpNum_ret=ms_max(tdCpNum,cpuNum2);
			break;
		case msev_tdcp_custom:
			tdCpNum_ret=(tdCpNum>0) ? tdCpNum : cpuNum2;
			break;
		case msev_tdcp_autocpu:
		default:
			tdCpNum_ret=cpuNum2;
			break;
	}
	if(tdCpNum_ret>msev_tdCp_numMax){
		ms_waring("Oh my god??tdCpNum_ret is out of range(0~%d),set to %d",msev_tdCp_numMax,msev_tdCp_numMax);
		tdCpNum_ret=msev_tdCp_numMax;
	}
	ms_debug("tdCpNum,tdCpType,cpuNum:%d,%d,%d",tdCpNum,tdCpType,cpuNum);
	return tdCpNum_ret;
}
static ms_void msev_innerapi_dcpIn(MSEVDCPContext *pdcp_ctt,ms_s32 fd)
{
	//如果监测到数据可读，则将输入存入连接池
	mslock_api_do(pdcp_ctt->pLockCtt_dcp);
	MSFIFOLISTContext *pFifoList_dcp= msev_innerapi_findOut(pdcp_ctt,pdcp_ctt->ppFifoListCtt_dcp, fd, pdcp_ctt->efd,ms_false);
	mslock_api_undo(pdcp_ctt->pLockCtt_dcp);
	if(ms_null!=pFifoList_dcp){
		MSEVClientContext*pEvClient_ctt=(MSEVClientContext*)pFifoList_dcp->ptr;
		ms_enDbg(MSWEB_DBG_RECV,"[%s-%s]dcpIn,send requ-info to cp(fd:%d)",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pEvClient_ctt->fd);
		if(msev_state_connecting!=pEvClient_ctt->state){
			pEvClient_ctt->state=msev_state_in;
		}
		pEvClient_ctt->lastReqTime_us=mstime_api_us();
		MSEVContext * pEv_ctt=(MSEVContext *)pdcp_ctt->pEv_ctt;
		pEvClient_ctt->method=pEv_ctt->method;
		pEvClient_ctt->route=pEv_ctt->route;
		pEvClient_ctt->pEvAuthent_ctt=&pEv_ctt->evAuthent_ctt;
		mslock_api_do(pdcp_ctt->pLockCtt_cp);
		msfifo_api_listIn(pdcp_ctt->ppFifoListCtt_cp,pFifoList_dcp);
		mslock_api_signal(pdcp_ctt->pLockCtt_cp,ms_false);
		mslock_api_undo(pdcp_ctt->pLockCtt_cp);
	}

}
static ms_void msev_innerapi_dcpOut(MSEVDCPContext *pdcp_ctt,ms_s32 fd)
{
	mslock_api_do(pdcp_ctt->pLockCtt_dcp);
	MSFIFOLISTContext *pFifoList_dcp= msev_innerapi_findOut(pdcp_ctt,pdcp_ctt->ppFifoListCtt_dcp, fd, pdcp_ctt->efd,ms_false);
	mslock_api_undo(pdcp_ctt->pLockCtt_dcp);
	if(ms_null!=pFifoList_dcp){
		MSEVClientContext*pEvClient_ctt=(MSEVClientContext*)pFifoList_dcp->ptr;
		ms_enDbg(MSWEB_DBG_RECV,"[%s-%s]dcpOut,send requ-info to cp(fd:%d)",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pEvClient_ctt->fd);
		if(msev_state_connecting==pEvClient_ctt->state){
			ms_waring("[%s] must connected first", pdcp_ctt->name);	
		}else{
			pEvClient_ctt->state=msev_state_out;
			pEvClient_ctt->lastReqTime_us=mstime_api_us();
			MSEVContext * pEv_ctt=(MSEVContext *)pdcp_ctt->pEv_ctt;
			pEvClient_ctt->method=pEv_ctt->method;
			pEvClient_ctt->route=pEv_ctt->route;
			pEvClient_ctt->pEvAuthent_ctt=&pEv_ctt->evAuthent_ctt;
			mslock_api_do(pdcp_ctt->pLockCtt_cp);
			msfifo_api_listIn(pdcp_ctt->ppFifoListCtt_cp,pFifoList_dcp);
			mslock_api_signal(pdcp_ctt->pLockCtt_cp,ms_false);
			mslock_api_undo(pdcp_ctt->pLockCtt_cp);
		}
	}
}
static ms_void msev_innerapi_dcpErr(MSEVDCPContext *pdcp_ctt,ms_s32 fd)
{
	mslock_api_do(pdcp_ctt->pLockCtt_dcp);
	MSFIFOLISTContext *pFifoList_dcp= msev_innerapi_findOut(pdcp_ctt,pdcp_ctt->ppFifoListCtt_dcp, fd, pdcp_ctt->efd,ms_false);
	mslock_api_undo(pdcp_ctt->pLockCtt_dcp);
	if(ms_null!=pFifoList_dcp){
		MSEVClientContext*pEvClient_ctt=(MSEVClientContext*)pFifoList_dcp->ptr;
		ms_enDbg(MSWEB_DBG_RECV,"[%s-%s]dcpErr,send requ-info to cp(fd:%d)",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pEvClient_ctt->fd);
		if(msev_state_connecting==pEvClient_ctt->state){
			close(pEvClient_ctt->fd);
			msfifo_api_listDemalloc(&pFifoList_dcp);
		}else{
			pEvClient_ctt->state=msev_state_close;
			pEvClient_ctt->lastReqTime_us=mstime_api_us();
			MSEVContext * pEv_ctt=(MSEVContext *)pdcp_ctt->pEv_ctt;
			pEvClient_ctt->method=pEv_ctt->method;
			pEvClient_ctt->route=pEv_ctt->route;
			pEvClient_ctt->pEvAuthent_ctt=&pEv_ctt->evAuthent_ctt;
			mslock_api_do(pdcp_ctt->pLockCtt_cp);
			msfifo_api_listIn(pdcp_ctt->ppFifoListCtt_cp,pFifoList_dcp);
			mslock_api_signal(pdcp_ctt->pLockCtt_cp,ms_false);
			mslock_api_undo(pdcp_ctt->pLockCtt_cp);
		}
	}
}
static ms_void msev_innerapi_dcp(MSEVDCPContext *pdcp_ctt)
{
	msthread_api_setName(pdcp_ctt->name);
	msepoll_event httpEvt[pdcp_ctt->max_event];
	ms_s32 evtNum=0;
	ms_s32 evtIndex=0;
	while(1){
		if(ms_true==pdcp_ctt->flag_stop){
			goto msstop;
		}
		memset(httpEvt,0,sizeof(msepoll_event));
		evtNum=msepoll_wait(pdcp_ctt->efd,(msepoll_event *)httpEvt,pdcp_ctt->max_event);
		if(evtNum>0){
			for(evtIndex=0;evtIndex<evtNum;evtIndex++){
				ms_verbose("[%s]msepoll_listen:%d,evtNum:%d,fd:%d,events:%d(msepollin:%d,%d)",pdcp_ctt->name,pdcp_ctt->efd,
					evtNum,httpEvt[evtIndex].data.fd,httpEvt[evtIndex].events,msepollin,msepollout);
				if(httpEvt[evtIndex].events&msepollhup||httpEvt[evtIndex].events&msepollerr){
					ms_waring("There is some thing wrong with  http listen fd,but I ignor it,maybe need to fix(even id %d)",httpEvt[evtIndex].events);
					msev_innerapi_dcpErr(pdcp_ctt,httpEvt[evtIndex].data.fd);
				}
				if(httpEvt[evtIndex].events&msepollin){
					msev_innerapi_dcpIn(pdcp_ctt,httpEvt[evtIndex].data.fd);
				}
				if(httpEvt[evtIndex].events&msepollout){
					msev_innerapi_dcpOut(pdcp_ctt,httpEvt[evtIndex].data.fd);
				}
			}
		}else{
			ms_msleep(1);
		}
		//丢掉过期或异常请求
		mslock_api_do(pdcp_ctt->pLockCtt_dcp);
		msev_innerapi_dcpExceptionHandle(pdcp_ctt,pdcp_ctt->ppFifoListCtt_dcp, pdcp_ctt->efd,pdcp_ctt->dcpSize,pdcp_ctt->name);
		mslock_api_undo(pdcp_ctt->pLockCtt_dcp);
	}
msstop:
	mslock_api_do(pdcp_ctt->pLockCtt_dcp);
	int totalnum=msfifo_api_listTotalNum(pdcp_ctt->ppFifoListCtt_dcp);
	mslock_api_undo(pdcp_ctt->pLockCtt_dcp);
	while(totalnum>0){
		mslock_api_do(pdcp_ctt->pLockCtt_dcp);
		MSFIFOLISTContext * msfifolist_ctt=msfifo_api_listOut(pdcp_ctt->ppFifoListCtt_dcp);
		totalnum=msfifo_api_listTotalNum(pdcp_ctt->ppFifoListCtt_dcp);
		mslock_api_undo(pdcp_ctt->pLockCtt_dcp);
		MSEVClientContext * pEvClient_ctt=(MSEVClientContext *)msfifolist_ctt->ptr;
		if(msepoll_del(pdcp_ctt->efd,pEvClient_ctt->fd,pEvClient_ctt->event_opt)<0){
			ms_error("msepoll_del-msepollin   failed(client_fd:%d)",pEvClient_ctt->fd);
		}
		if(ms_null!=msfifolist_ctt){
			close(pEvClient_ctt->fd);
			msfifo_api_listDemalloc(&msfifolist_ctt);
		}
	}
	ms_debug("STOP============>%s",pdcp_ctt->name);
	pdcp_ctt->flag_stop=ms_false;
}
ms_void msev_innerapi_cp(MSEVCPContext *pCp_ctt)
{
	msthread_api_setName(pCp_ctt->name);
	MSFIFOLISTContext * *ppFifoListCtt_cp=pCp_ctt->ppFifoListCtt_cp;
	MSFIFOLISTContext *pFifiList_ctt=ms_null;
	MSEVClientContext*pEvClient_ctt=ms_null;
	uint32_t totalnum=0;
	while(1){
		if(ms_true==pCp_ctt->flag_stop){
			goto msstop;
		}
		//get request_list num
	mslock_api_do(pCp_ctt->pMslockCtt_cp);
		totalnum=msfifo_api_listTotalNum(ppFifoListCtt_cp);
		if(totalnum>0){
			//get one request
			pFifiList_ctt=msfifo_api_listOut(ppFifoListCtt_cp);
		}else{//没有成员再陷入条件信号的等待
			while(1){//防止虚拟唤醒，增加是否有成员的判断
				mslock_api_wait(pCp_ctt->pMslockCtt_cp);
				if(ms_true==pCp_ctt->flag_stop){
					goto msstop;
				}
				totalnum=msfifo_api_listTotalNum(ppFifoListCtt_cp);
				if(totalnum>0){
					pFifiList_ctt=msfifo_api_listOut(ppFifoListCtt_cp);
					break;
				}
			}
		}
	mslock_api_undo(pCp_ctt->pMslockCtt_cp);
		MSEVContext * pEv_ctt=(MSEVContext *)pCp_ctt->pEv_ctt;
		if(totalnum>0){
			//do open
			if(ms_null!=pFifiList_ctt){
				pEvClient_ctt=pFifiList_ctt->ptr;
				if(msev_state_connecting==pEvClient_ctt->state){
					if(ms_true==msev_innerapi_isException(pEvClient_ctt,ms_false) ){
						msfifo_api_listDemalloc(&pFifiList_ctt);
					}else{
						ms_enDbg(MSWEB_DBG_RECV,"[%s]start	to recv %s,fifototalnum:%d",pEvClient_ctt->name,pEvClient_ctt->ipaddr,totalnum);
						if(pEv_ctt->onConnect(pEv_ctt->cbArgs,pEvClient_ctt)<0){
							//ms_debug("pheader_fifolist_ctt-------------num:%d",msfifo_api_listTotalNum(ppFifoList_ctt));
							msfifo_api_listDemalloc(&pFifiList_ctt);
						}else{
							//如果是长连接业务
							pEvClient_ctt->lastReqTime_us=mstime_api_us();
							pEvClient_ctt->state=msev_state_connected;
							if(msepoll_add(pCp_ctt->msepoll_fd,pEvClient_ctt->fd,pEvClient_ctt->event_opt)<0){
								ms_error("msepoll_add-msepollin   failed(client_fd:%d)",pEvClient_ctt->fd);
							}
							mslock_api_do(pCp_ctt->pMslockCtt_dcp);
							msfifo_api_listIn(pCp_ctt->ppFifoListCtt_dcp,pFifiList_ctt);
							mslock_api_undo(pCp_ctt->pMslockCtt_dcp);	
						}
					}
				}else if(msev_state_in==pEvClient_ctt->state){
					if(ms_null!=pEv_ctt->onRecv){
						pEv_ctt->onRecv(pEv_ctt->cbArgs,pEvClient_ctt);
						if(msepoll_add(pCp_ctt->msepoll_fd,pEvClient_ctt->fd,pEvClient_ctt->event_opt)<0){
							ms_error("msepoll_add-msepollin   failed(client_fd:%d)",pEvClient_ctt->fd);
						}
					}
					pEvClient_ctt->state=msev_state_connected;
					mslock_api_do(pCp_ctt->pMslockCtt_dcp);
					msfifo_api_listIn(pCp_ctt->ppFifoListCtt_dcp,pFifiList_ctt);
					mslock_api_undo(pCp_ctt->pMslockCtt_dcp);
				}else if(msev_state_out==pEvClient_ctt->state){
					if(ms_null!=pEv_ctt->onSend){
						pEv_ctt->onSend(pEv_ctt->cbArgs,pEvClient_ctt);
						if(msepoll_add(pCp_ctt->msepoll_fd,pEvClient_ctt->fd,pEvClient_ctt->event_opt)<0){
							ms_error("msepoll_add-msepollin   failed(client_fd:%d)",pEvClient_ctt->fd);
						}
					}
					pEvClient_ctt->state=msev_state_connected;
					mslock_api_do(pCp_ctt->pMslockCtt_dcp);
					msfifo_api_listIn(pCp_ctt->ppFifoListCtt_dcp,pFifiList_ctt);
					mslock_api_undo(pCp_ctt->pMslockCtt_dcp);
				}else if(msev_state_close==pEvClient_ctt->state){
					if(ms_null!=pEv_ctt->onClose){
						pEv_ctt->onClose(pEv_ctt->cbArgs,pEvClient_ctt);
					}
					msfifo_api_listDemalloc(&pFifiList_ctt);
					pEvClient_ctt->state=msev_state_closed;
				}
			}else{
				ms_error("pFifiList_ctt is null");
			}
		}
	}
msstop:
	mslock_api_do(pCp_ctt->pMslockCtt_cp);
	totalnum=msfifo_api_listTotalNum(ppFifoListCtt_cp);
	mslock_api_undo(pCp_ctt->pMslockCtt_cp);
	while(totalnum>0){
		mslock_api_do(pCp_ctt->pMslockCtt_cp);
		pFifiList_ctt=msfifo_api_listOut(ppFifoListCtt_cp);
		totalnum=msfifo_api_listTotalNum(ppFifoListCtt_cp);
		mslock_api_undo(pCp_ctt->pMslockCtt_cp);
		if(ms_null!=pFifiList_ctt){
			pEvClient_ctt=pFifiList_ctt->ptr;
			close(pEvClient_ctt->fd);
			msfifo_api_listDemalloc(&pFifiList_ctt);
		}
	}
	ms_debug("STOP============>%s",pCp_ctt->name);
	pCp_ctt->flag_stop=ms_false;
}
ms_void msev_api_logfile(MSEVClientContext * pEvClient_ctt,const char *format,...)
{
	ms_byte lastReqTime_us[128]={0};
	mstime_api_us2DTime(&pEvClient_ctt->lastReqTime_us, mstime_fmt_datetime_ex4, lastReqTime_us);

	va_list arg;
	va_start(arg,format);
	ms_byte exinfo[1024]={0};
	/*获取参数时，一定要小心。否则会导致段错误*/
	vsnprintf(exinfo,ms_bufsize(exinfo), format,arg);
	ms_logfile(FILE_LOG_MSWEB, "[%s]请求时间%s，地址%s，原因:%s", pEvClient_ctt->name,lastReqTime_us, pEvClient_ctt->ipaddr,exinfo);
	va_end(arg);
}
/*操作记录日志*/
ms_void msev_api_logRecord(ms_byte * ipaddr,char *format,...)
{
	va_list arg;
	va_start(arg,format);
	ms_byte exinfo[1024]={0};
	/*获取参数时，一定要小心。否则会导致段错误*/
	vsnprintf(exinfo,ms_bufsize(exinfo), format,arg);
	ms_logfile(FILE_LOG_OPRECORD, "IP地址%s，操作情况:%s", ipaddr,exinfo);
	va_end(arg);
}

ms_void msev_api_enpOutstr(ms_string  ms_out outstr,ms_string key,ms_string exter_str)
{
	ms_pamcheck(outstr, "outstr");
	msdenc_api_encStr2(outstr,key,ms_null,FLAG,exter_str);
}

ms_s32 msev_api_recv(MSEVClientContext * pEvClient_ctt,WEBREQUESTContext *pReq_ctt,ms_byte *pBuf,int maxLen)
{
	//read client requset info
	int len = 0;
	int len_read = 0;
	time_t Etimep_read=mstime_api_sec();
	ms_byte outbuf[2048]={0};
	ms_byte desinfo[1024]={0};
/*读取请求数据*/	
ms_read:	
	len = msnet_api_epollRecv3(pEvClient_ctt->fd,&pBuf[len_read],maxLen-len_read);
	if(len<0){
		//读取内容失败
		msprotocol_api_replay_desinfo(MSPTC_VERSION_HTTP, outbuf, NETSTATE_CODE_ERRORIO,desinfo,"Read the request data failed");
		msev_api_logfile(pEvClient_ctt, "读取内容失败");
		ms_errGoto(ms_falied,"%s",desinfo);
	}else{
		len_read+=len;
	}
/*解析读取的数据*/
	ms_verbose("[%s]Recv data from %s (fd:%d)\r\n(buflen:%ld)%s",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pEvClient_ctt->fd,maxLen,pBuf);
	ms_stru0(pReq_ctt, WEBREQUESTContext);
	ms_byte str_parase_out[256]={0};
	if(ms_false==msptc_api_parseRequest(pBuf,pReq_ctt,str_parase_out)){
		//拦截内容格式错误的请求
		msev_api_logfile(pEvClient_ctt, "因为内容格式错误被丢弃。如果内容为乱码，则可能是HTTPS请求(%s)",pBuf);
		msweb_api_badRequest(outbuf);
		ms_errGoto(ms_falied,"[%s]Bad Request:%s(ipaddr:%s,url:%s)",pEvClient_ctt->name, str_parase_out,pEvClient_ctt->ipaddr,pReq_ctt->url);
	}
	//过滤掉不在规则内的方法
	if(ms_null!=pEvClient_ctt->method&&(!msstr_api_isCasestr(pEvClient_ctt->method, pReq_ctt->method))){
		msev_api_logfile(pEvClient_ctt, "不支持的方法(%s)",pBuf);
		msweb_api_methodNotAllowed(outbuf);
		ms_warGoto(ms_falied,"[%s]Method Not Allowed:%s(ipaddr:%s,url:%s)",pEvClient_ctt->name, pReq_ctt->method,pEvClient_ctt->ipaddr,pReq_ctt->url);
	}
	//过滤掉探测攻击
	if(ms_strncmp_saeq(pReq_ctt->url, "/")||ms_strncmp_saeq(pReq_ctt->url, "/master-status")){
		msev_api_logfile(pEvClient_ctt, "不支持的URL(%s)",pBuf);
		msweb_api_badRequest(outbuf);
		ms_warGoto(ms_falied,"[%s]URL Not Allowed:%s(ipaddr:%s,url:%s)",pEvClient_ctt->name, pReq_ctt->url,pEvClient_ctt->ipaddr,pReq_ctt->url);
	}
/*确定数据是否读取完毕*/
	//提交的内容过长
	if(ms_noLess(pReq_ctt->content_len, ms_bufsize(pReq_ctt->content))){
		msprotocol_api_replay_desinfo(MSPTC_VERSION_HTTP,outbuf,NETSTATE_CODE_BAD_REQUEST,desinfo, 
			"Content len error:content_len(%d) is out of range %ld",pReq_ctt->content_len,ms_bufsize(pReq_ctt->content));
		msev_api_logfile(pEvClient_ctt, "内容过长(%d)，超出范围0～%ld",pReq_ctt->content_len,ms_bufsize(pReq_ctt->content));
		ms_errGoto(ms_falied,"%s",desinfo);
	}	
	if(pReq_ctt->content_len>ms_buflen(pReq_ctt->content)){
		ms_usleep(2);
		if(mstime_api_counterAsyncSec(&Etimep_read,1)){//读取内容超时，超时时间1秒
			msprotocol_api_replay_desinfo(MSPTC_VERSION_HTTP,outbuf,NETSTATE_CODE_BAD_REQUEST,desinfo, 
				"Read content timeout,read_content_len:%d,%ld",pReq_ctt->content_len,ms_buflen(pReq_ctt->content));
			msev_api_logfile(pEvClient_ctt, "读取内容超时，超时时间1秒。内容长度%d，已读取%ld",pReq_ctt->content_len,ms_bufsize(pReq_ctt->content));
			ms_errGoto(ms_falied,"%s",desinfo);
		}
		ms_dbgGoto(ms_read, "Need  read context,content_len,read_content_len:%d,%ld",pReq_ctt->content_len,ms_buflen(pReq_ctt->content));
	}

/*进行鉴权*/	
	if(pEvClient_ctt->pEvAuthent_ctt->flag_reqAuthent){
		ms_byte realPath[256]={0};
		msstr_api_getUrlRealPath(pReq_ctt->url,realPath);
		if(ms_null==pEvClient_ctt->pEvAuthent_ctt->ignorPath||
			(ms_false==msstr_api_isCasestr(pEvClient_ctt->pEvAuthent_ctt->ignorPath, realPath))){
		//获取内容	
			ms_byte *pContext=ms_null;
			ms_byte context[mscfg_maxlen_recv+1]={0};
			if(ms_buflen(pReq_ctt->extern_data.http_rd.webhost_info.url_param)>0){
				ms_byte url_param[512];
				ms_strcpy(url_param, pReq_ctt->extern_data.http_rd.webhost_info.url_param);
				ms_string str_array_item[16];
				//ms_info("url_param:%s", url_param);
				ms_s32 num_param=msstr_api_split2(url_param, "&module", str_array_item);
				if(num_param>1){
					//ms_info("num_param:%d,str_array_item:%s", num_param,str_array_item[0]);
					ms_strcat(context,str_array_item[0]);pContext=context;
				}
			}
			if(pReq_ctt->content_len>0){
				ms_strcat(context,pReq_ctt->content);pContext=context;
			}
		//算摘要
			DECSTRRet ret_enpmatch=msdenc_api_decStr(pReq_ctt->url,pEvClient_ctt->pEvAuthent_ctt->pStrPrivatekey,
				pContext,ms_true,pEvClient_ctt->pEvAuthent_ctt->timeoutSec);
			if(ret_enpmatch<decstr_ret_ok){
				if(ms_true==pEvClient_ctt->pEvAuthent_ctt->flag_web){
					msweb_api_ok(outbuf);
					ms_bool flag_retlogin=(decstr_ret_timeout==ret_enpmatch) ? ms_true : ms_false;
					msmsusrctl_api_unAuthorized(outbuf, flag_retlogin);
				}else{
					msweb_api_unauthorizedAccess(outbuf,ret_enpmatch);
				}
				msev_api_logfile(pEvClient_ctt, "证书未通过，URL地址：%s",pReq_ctt->url);
				ms_warGoto(ms_falied,"[%s]The certification was not passed(ipaddr:%s,url:%s)",pEvClient_ctt->name,pEvClient_ctt->ipaddr,pReq_ctt->url);
			}
		}
	}
	return len_read;
ms_falied:
/*反馈错误信息*/	
	if(0<pEvClient_ctt->fd){
		ms_s32 send_len=msnet_api_epollSend3(pEvClient_ctt->fd,outbuf,strlen(outbuf)); 
	}
/*关闭连接*/		
	ms_close(pEvClient_ctt->fd);
	return -1;
}
ms_string msev_api_getReqInfo(MSEVContext *pmsev_ctt,ms_string desInfo,ms_string outStr)
{
	ms_u32 total=msev_innerapi_getNumCp(pmsev_ctt)+ msev_innerapi_getNumDcp(pmsev_ctt);
	ms_sprintfs(outStr,"%s: %d(cp:%d+dcp:%d)" ,desInfo,total,	
		msev_innerapi_getNumCp(pmsev_ctt), msev_innerapi_getNumDcp(pmsev_ctt));
	return outStr;
}
ms_void msev_api_createServer(MSEVContext *pEv_ctt)
{	
	if(ms_noMore(pEv_ctt->port, 0)){
		ms_errNoret("[%s]invalid port %d",pEv_ctt->name,pEv_ctt->port);
	}

	URLContext evUrl_ctt;
	ms_memset0(&evUrl_ctt, ms_bufsize(URLContext));
	URLContext *pEvUrl_ctt=(ms_null!=pEv_ctt->purlval) ? &pEv_ctt->purlval->url_ctt  : (&evUrl_ctt);

	ms_u32 step_index=0;
//设置服务名称
	ms_debug("====>%d.[%s]Set service name",++step_index,pEv_ctt->name);
	msthread_api_setName(pEv_ctt->name);
//初始化资源锁
	MSLOCKContext mslockCtt_dcp;
	MSLOCKContext mslockCtt_cp;
	ms_memset(&mslockCtt_dcp, 0, ms_bufsize(MSLOCKContext));
	ms_memset(&mslockCtt_cp, 0, ms_bufsize(MSLOCKContext));
	ms_debug("%d.1.[%s] init lock",step_index,pEv_ctt->name);
	ms_byte lockName[512]={0};
	ms_sprintfs(lockName,"mslockCtt_%s_dcp",pEv_ctt->name);
	ms_debug("%d.1.1.[%s] init lock %s",step_index,pEv_ctt->name,lockName);
	mslock_api_init(&mslockCtt_dcp,lockName,lockType_mutex);
	ms_sprintfs(lockName,"mslockCtt_%s_cp",pEv_ctt->name);
	ms_debug("%d.1.2.[%s] init lock %s",step_index,pEv_ctt->name,lockName);
	mslock_api_init(&mslockCtt_cp,lockName,lockType_cond);

//创建连接池	
	//获取连接池个数
	ms_u32 cpNum=msev_innerapi_getTdCpNum(pEv_ctt->tdCpNum,pEv_ctt->tdCpType);
	ms_debug("%d.2.[%s] Gets the number of connection pools used:%d",step_index,pEv_ctt->name,cpNum);

	ms_debug("%d.2.[%s] malloc pmsthreadctt_gw and pmsgw_ctt_list",step_index,pEv_ctt->name);
	ms_byte mal_name[128]={0};
	MSTHREADContext *pTdCp_ctt=ms_null;
	ms_sprintfs(mal_name, "pTdCp_ctt(%s)", pEv_ctt->name);
	ms_mallocDes_goto(ms_stopserver, pTdCp_ctt, (cpNum * sizeof(MSTHREADContext)),"MSTHREADContext", mal_name);
	ms_sprintfs(mal_name, "pCp_ctt(%s)", pEv_ctt->name);
	ms_mallocDes_goto(ms_stopserver, pEv_ctt->pCp_ctt, (cpNum * sizeof(MSEVCPContext)),"MSEVCPContext", mal_name);
	
	URLProtocol *pHttp_ptl=msptc_api_matchByPtcindex(msptc_http);
	MSFIFOLISTContext * pHfifoList_dcp=ms_null;
	MSFIFOLISTContext * pHfifoList_cp=ms_null;
//创建检测连接池	
	MSTHREADContext tdDcp_ctt;
	MSEVDCPContext evDcp_ctt;
	evDcp_ctt.flag_stop=ms_false;
	ms_sprintfs(evDcp_ctt.name,"%s_dcp",pEv_ctt->name);
	evDcp_ctt.ppFifoListCtt_cp=&pHfifoList_cp;
	evDcp_ctt.pLockCtt_cp=&mslockCtt_cp;
	evDcp_ctt.ppFifoListCtt_dcp=&pHfifoList_dcp;
	evDcp_ctt.pLockCtt_dcp=&mslockCtt_dcp;
	evDcp_ctt.pEv_ctt=pEv_ctt;
	evDcp_ctt.dcpSize=pEv_ctt->dcpSize;
	evDcp_ctt.max_event=(10+pEv_ctt->dcpSize);
	ms_debug("%d.1.[%s]open epoll(dcp)",step_index,pEv_ctt->name);
	evDcp_ctt.efd=msepoll_open(evDcp_ctt.max_event);
	if(0>evDcp_ctt.efd){
		ms_errNoret("msepoll_open failed");
	}	
	ms_debug("%d.2.[%s]Create task:%s_dcp",step_index,pEv_ctt->name,pEv_ctt->name);
	msthread_api_create(&tdDcp_ctt, evDcp_ctt.name,msev_innerapi_dcp, &evDcp_ctt);

	ms_u32 cp_index=0;
	ms_debug("%d.3.[%s] Create task:%s_cp",step_index,pEv_ctt->name,pEv_ctt->name);
	for(cp_index=0;cp_index<cpNum;cp_index++){
		MSEVCPContext * pCp_ctt=&pEv_ctt->pCp_ctt[cp_index];
		pCp_ctt->flag_stop=ms_false;
		//设置连接池名称
		ms_sprintfs(pCp_ctt->name, "%s_cp%d",pEv_ctt->name, cp_index);
		pCp_ctt->ppFifoListCtt_cp=&pHfifoList_cp;
		pCp_ctt->pMslockCtt_cp=&mslockCtt_cp;
		pCp_ctt->ppFifoListCtt_dcp=&pHfifoList_dcp;
		pCp_ctt->pMslockCtt_dcp=&mslockCtt_dcp;
		pCp_ctt->purl_ptl=pHttp_ptl;
		pCp_ctt->purl_ctt=pEvUrl_ctt;
		pCp_ctt->pEv_ctt=pEv_ctt;
		pCp_ctt->cp_index=cp_index;
		pCp_ctt->msepoll_fd=evDcp_ctt.efd;
		msthread_api_create(&pTdCp_ctt[cp_index], pCp_ctt->name,msev_innerapi_cp, pCp_ctt);
	}
	
ms_debug("====>%d.[%s]Open server and enter listen state",++step_index,pEv_ctt->name);	
	ms_stru0(pEvUrl_ctt, URLContext);
	ms_sprintfs(pEvUrl_ctt->url,"http://127.0.0.1:%d",pEv_ctt->port);
	ms_debug("====>%d.1.[%s]Open server :%s",step_index,pEv_ctt->name,pEvUrl_ctt->url);	
	pEvUrl_ctt->opt.http.listen=1;
	if(pHttp_ptl->url_open(pEvUrl_ctt)<0){
		ms_errGoto(ms_stopserver,"Open %s failed",pEvUrl_ctt->url);
	}
	
ms_debug("====>%d.[%s]Open listen epoll",++step_index,pEv_ctt->name);	
	int max_event=2;
	int efd_listen=msepoll_open(max_event);
	if(0>efd_listen){
		pHttp_ptl->url_close(pEvUrl_ctt);
		ms_errNoret("msepoll_open failed");
	}	
ms_debug("====>%d.[%s]And server fd to  listen epoll",++step_index,pEv_ctt->name);	
	int listen_fd=pHttp_ptl->priv_func.http.get_listen_handle(pEvUrl_ctt);
	msepoll_add(efd_listen,listen_fd,msepollin);
	ms_debug("====>%d.listen client request",++step_index);	
	while(1){	
		//是否要求退出服务程序
		if((ms_null!=pEv_ctt->onStop) && (ms_false==pEv_ctt->onStop(pEv_ctt->cbArgs))){
			ms_warGoto(ms_stopserver, "onStop------stop");
		}
		msepoll_event httpEvent[max_event];
		memset(httpEvent,0,sizeof(msepoll_event));
		int numEvent=msepoll_wait(efd_listen,(msepoll_event *)httpEvent,max_event);
		if(numEvent>0){
			int eventIndex=0;
			for(eventIndex=0;eventIndex<numEvent;eventIndex++){
				ms_verbose("[%s]efd_listen:%d,numEvent:%d,fd:%d",pEv_ctt->name,efd_listen,numEvent,httpEvent[eventIndex].data.fd);
				if(listen_fd==httpEvent[eventIndex].data.fd){
					if(httpEvent[eventIndex].events&msepollhup||httpEvent[eventIndex].events&msepollerr){
						ms_waring("There is some thing wrong with listen fd,but I ignor it,maybe need to fix(even id %d)",httpEvent[eventIndex].events);
					}else if(httpEvent[eventIndex].events&msepollin){
						int client_fd=pHttp_ptl->priv_func.http.accept(pEvUrl_ctt);//接收客户端
						if(client_fd<0){
							ms_error("Client accept failed,client_fd:%d",client_fd);
						}else if(client_fd==pEvUrl_ctt->fd){
							ms_error("Error Client fd,the client_fd(%d) is equ serverfd(%d)",client_fd,pEvUrl_ctt->fd);
						}else if(client_fd>0){
							HTTPContext * pHttp_ctt=(HTTPContext *)pEvUrl_ctt->priv_data;
							ms_byte ipaddr_client[256]={0};
#if ENABLE_IPV6
							ms_byte bufIpaddr[256]={0};
							msnet_api_getIpaddr((struct sockaddr *)&pHttp_ctt->tcpctt.peer_info.sockaddrs6,bufIpaddr);
							ms_sprintfs(ipaddr_client,"%s",bufIpaddr);
#else					
							ms_sprintfs(ipaddr_client,"%s",inet_ntoa(pHttp_ctt->tcpctt.peer_info.sockaddrs.sin_addr));
#endif
							if(ms_null!=pEv_ctt->pflag_appInit&&ms_false==(*pEv_ctt->pflag_appInit)){
							//外部未初始化完成，则立即返回相应报文
								ms_debug("[%s]must be init at frist,autoclose (fd:%d,%s)",pEv_ctt->name,client_fd,ipaddr_client);
								char outbuf[1024]={0};
								msweb_api_initFirst(outbuf);
								int len=msnet_api_epollSend3(client_fd,outbuf,ms_buflen(outbuf)); 
								if(!(len>0)){
									ms_error("[%s]msnet_api_epollSend3 failed(fd:%d,%s)",pEv_ctt->name,client_fd,ipaddr_client);
								}
								ms_close(client_fd);
							}else if(ms_null!=pEv_ctt->pflag_disable&&ms_true==(*pEv_ctt->pflag_disable)){
							//如果暂时暂停访问，则立即返回相应报文
								ms_debug("[%s]disable out,autoclose  (fd:%d,%s)",pEv_ctt->name,client_fd,ipaddr_client);
								char outbuf[1024]={0};
								msweb_api_disableOut(outbuf);
								int len=msnet_api_epollSend3(client_fd,outbuf,ms_buflen(outbuf)); 
								if(!(len>0)){
									ms_error("[%s]msnet_api_epollSend3 failed(fd:%d,%s)",pEv_ctt->name,client_fd,ipaddr_client);
								}
								ms_close(client_fd);
							}else if((ms_true==msev_innerapi_ictEnter(&pEv_ctt->pIct_ctt,ipaddr_client,client_fd,
								pEv_ctt->ictAccessTime_us,
								pEv_ctt->flag_ictAccess, pEv_ctt->flag_ictResAddr))){
								//客户端拦截检测
								ms_verbose("[%s]Client access is blocked,autoclose it(fd:%d,%s)",pEv_ctt->name,client_fd,ipaddr_client);
							}else{
								/*push list1 to fifo*/
								MSFIFOLISTContext *pFifoList_ctt=msfifo_api_listMalloc(sizeof(MSEVClientContext),"dcp_fifolist");
								if(ms_null!=pFifoList_ctt){
									MSEVClientContext * pEvClient_ctt=(MSEVClientContext *)pFifoList_ctt->ptr;
									ms_strcpy(pEvClient_ctt->name, pEv_ctt->name);
									//ms_info("[%#x-%s-%s]port:%d",pEv_ctt->name,pEv_ctt->name,ipaddr_client,pEv_ctt->port);
									ms_strcpy(pEvClient_ctt->ipaddr, ipaddr_client);
									pEvClient_ctt->fd=client_fd;
									pEvClient_ctt->state=msev_state_connecting;
									pEvClient_ctt->connectTime_us=mstime_api_us();
									pEvClient_ctt->lastReqTime_us=mstime_api_us();
									pEvClient_ctt->event_opt=msepollin;
									ms_enDbg(MSWEB_DBG_RECV,"[%s-%s]send requ-info to dcp(fd:%d)",pEv_ctt->name,ipaddr_client,client_fd);
									mslock_api_do(&mslockCtt_dcp);
									//将连接信息放入检测连接池
									msfifo_api_listIn(&pHfifoList_dcp,pFifoList_ctt);								
									if(msepoll_add(evDcp_ctt.efd,client_fd,pEvClient_ctt->event_opt)<0){
										ms_error("[%s]msepoll_add-msepollin   failed(client_fd:%d-ip:%s)",pEv_ctt->name,client_fd,ipaddr_client);
									}else{
										ms_enDbg(MSWEB_DBG_RECV,"[%s-%s]msepoll_add-msepollin   sucess",pEv_ctt->name,ipaddr_client);
									}
									//ms_debug("pHfifoList_dcp-------------totalnum:%d,client_fd:%d",msfifo_api_listTotalNum(&pHfifoList_dcp),client_fd);
									mslock_api_undo(&mslockCtt_dcp);
								}else{
									ms_error("msfifo_api_listMalloc failed,drop clent request,ip:%s",ipaddr_client);
								}
							}
						}
					}else{
						ms_debug("default fd:%d  event:%d",httpEvent[eventIndex].data.fd,httpEvent[eventIndex].events);
					}
				}
			}		
		}else{
			ms_usleep(50);
		}
}
ms_stopserver:	
ms_debug("====>%d.[%s]remove server fd to  listen epoll",++step_index,pEv_ctt->name);	
	msepoll_del(efd_listen,listen_fd,msepollin);

ms_debug("====>%d.[%s]close listen epoll",++step_index,pEv_ctt->name);	
	msepoll_close(&efd_listen);
	
ms_debug("====>%d.[%s]close server ",++step_index,pEv_ctt->name);	
	if(pHttp_ptl->url_close(pEvUrl_ctt)<0){
		ms_error("url_close %s failed",pEvUrl_ctt->url);
	}
//stop epollrecv	
ms_debug("====>%d.[%s]deinit  epollrecv info",++step_index,pEv_ctt->name);
		ms_debug("%d.1.[%s]stop  epollrecv task",step_index,pEv_ctt->name);
		evDcp_ctt.flag_stop=ms_true;
		time_t sys_base=mstime_api_sec();
		while(ms_true==evDcp_ctt.flag_stop){
			ms_debug("Wait for recvthread_fifo stop");
			ms_msleep(100);
			if(ms_true==mstime_api_counterAsyncSec(&sys_base, ms_seconds(30))){
				break;
			}
		}
		msthread_api_destroy(&tdDcp_ctt);
		ms_debug("%d.1.[%s]close  epollrecv rpoll",step_index,pEv_ctt->name);
		msepoll_close(&evDcp_ctt.efd);
//stop gw	
ms_debug("====>%d.[%s]deinit  gw info",++step_index,pEv_ctt->name);
	ms_debug("====>%d.1.[%s]stop  gw task",step_index,pEv_ctt->name);
	ms_u32 stop_num=0;
	for(cp_index=0;cp_index<cpNum;cp_index++){
		pEv_ctt->pCp_ctt[cp_index].flag_stop=ms_true;
	}
//发送停止信号
	mslock_api_do(&mslockCtt_cp);
	mslock_api_signal(&mslockCtt_cp,ms_true);
	mslock_api_undo(&mslockCtt_cp);
	
	sys_base=mstime_api_sec();
	while(stop_num!=cpNum){
		stop_num=0;
		ms_msleep(100);
		for(cp_index=0;cp_index<cpNum;cp_index++){
			if(ms_false==pEv_ctt->pCp_ctt[cp_index].flag_stop){
				stop_num++;
			}
		}
		ms_debug("Wait for pTdCp_ctt stop:%d",stop_num);
		if(ms_true==mstime_api_counterAsyncSec((time_t * )&sys_base, ms_seconds(60))){
			break;
		}
	}
	for(cp_index=0;cp_index<cpNum;cp_index++){
		msthread_api_destroy(&pTdCp_ctt[cp_index]);
	}		
	ms_debug("====>%d.2.[%s]deinit  lock",step_index,pEv_ctt->name);
	mslock_api_deinit(&mslockCtt_cp);
	mslock_api_deinit(&mslockCtt_dcp);
	ms_debug("====>%d.3.[%s]demalloc  pTdCp_ctt and pmsgw_ctt_list",step_index,pEv_ctt->name);
	ms_deMalloc(pTdCp_ctt);
	ms_deMalloc(pEv_ctt->pCp_ctt);

	msev_innerapi_ictExit(&pEv_ctt->pIct_ctt);
}
#undef MSWEB_C

